package cn.iocoder.yudao.module.javainfo.service.productsort;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.javainfo.controller.admin.productsort.vo.ProductSortListReqVO;
import cn.iocoder.yudao.module.javainfo.controller.admin.productsort.vo.ProductSortSaveReqVO;
import cn.iocoder.yudao.module.javainfo.dal.dataobject.productsort.ProductSortDO;
import cn.iocoder.yudao.module.javainfo.dal.mysql.productsort.ProductSortMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.javainfo.enums.ErrorCodeConstants.*;

/**
 * 商品分类 Service 实现类
 */
@Service
@Validated
public class ProductSortServiceImpl implements ProductSortService {

    @Resource
    private ProductSortMapper productSortMapper;

    @Override
    public Long createProductSort(ProductSortSaveReqVO createReqVO) {
        // 校验正确性
        validateProductSortForCreateOrUpdate(null, createReqVO.getParentId(), createReqVO.getName());

        // 插入商品分类
        ProductSortDO productSort = BeanUtils.toBean(createReqVO, ProductSortDO.class);
        productSortMapper.insert(productSort);
        return productSort.getId();
    }

    @Override
    public void updateProductSort(ProductSortSaveReqVO updateReqVO) {
        // 校验正确性
        validateProductSortForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());

        // 更新商品分类
        ProductSortDO updateObj = BeanUtils.toBean(updateReqVO, ProductSortDO.class);
        productSortMapper.updateById(updateObj);
    }

    @Override
    public void deleteProductSort(Long id) {
        // 校验是否存在
        validateProductSortExists(id);
        // 校验是否有子分类
        if (productSortMapper.selectCountByParentId(id) > 0) {
            throw exception(PRODUCT_SORT_EXISTS_CHILDREN);
        }
        // 删除商品分类
        productSortMapper.deleteById(id);
    }

    @Override
    public void deleteProductSortList(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        // 校验是否存在
        ids.forEach(this::validateProductSortExists);
        // 校验是否有子分类
        ids.forEach(id -> {
            if (productSortMapper.selectCountByParentId(id) > 0) {
                throw exception(PRODUCT_SORT_EXISTS_CHILDREN);
            }
        });
        // 批量删除
        productSortMapper.deleteByIds(ids);
    }

    private void validateProductSortForCreateOrUpdate(Long id, Long parentId, String name) {
        // 校验自己存在
        validateProductSortExists(id);
        // 校验父分类存在
        validateParentProductSortExists(id, parentId);
        // 校验商品分类名的唯一性
        validateProductSortNameUnique(id, parentId, name);
    }

    private void validateParentProductSortExists(Long id, Long parentId) {
        if (parentId == null || parentId == 0) {
            return;
        }
        // 不能设置自己为父分类
        if (Objects.equals(parentId, id)) {
            throw exception(PRODUCT_SORT_PARENT_ERROR);
        }
        // 父分类不存在
        ProductSortDO parentProductSort = productSortMapper.selectById(parentId);
        if (parentProductSort == null) {
            throw exception(PRODUCT_SORT_PARENT_NOT_EXISTS);
        }
        // 父分类不能是自己的子分类
        if (id == null) {
            return;
        }
        List<ProductSortDO> children = getChildProductSortList(id);
        if (children.stream().anyMatch(dept -> Objects.equals(dept.getId(), parentId))) {
            throw exception(PRODUCT_SORT_PARENT_IS_CHILD);
        }
    }

    private void validateProductSortNameUnique(Long id, Long parentId, String name) {
        ProductSortDO productSort = productSortMapper.selectByParentIdAndName(parentId, name);
        if (productSort == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的商品分类
        if (id == null) {
            throw exception(PRODUCT_SORT_NAME_DUPLICATE);
        }
        if (!Objects.equals(productSort.getId(), id)) {
            throw exception(PRODUCT_SORT_NAME_DUPLICATE);
        }
    }

    private List<ProductSortDO> getChildProductSortList(Long id) {
        List<ProductSortDO> children = productSortMapper.selectList(
                ProductSortDO::getParentId, id);
        // 递归获取子分类
        List<ProductSortDO> result = CollUtil.newArrayList(children);
        children.forEach(child -> result.addAll(getChildProductSortList(child.getId())));
        return result;
    }

    @Override
    public ProductSortDO getProductSort(Long id) {
        return productSortMapper.selectById(id);
    }

    @Override
    public List<ProductSortDO> getProductSortList(ProductSortListReqVO reqVO) {
        return productSortMapper.selectList(reqVO);
    }

    private void validateProductSortExists(Long id) {
        if (id == null) {
            return;
        }
        ProductSortDO productSort = productSortMapper.selectById(id);
        if (productSort == null) {
            throw exception(PRODUCT_SORT_NOT_EXISTS);
        }
    }

}

